Java基础知识(六)

Author Avatar
子语 2017 - 10 - 09
  • 在其它设备中阅读本文章

关键字this

this调用属性

class Book {
    private String title;
    private double price;

    public Book(String t, double p) {
        title = t;
        price = p;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book book = new Book("Java开发", 66.6);
        System.out.println(book.getInfo());
    }
}

上述代码中,构造方法的功能是为title和price进行初始化,但是存在不足:方法中的参数名t和p无法表示具体含义。构造方法的功能是为类的属性初始化,参数名最好与属性名一致。

public Book(String title, double price) {
    title = title;
    price = price;
}

修改后,发现构造方法中的参数值并未传递到属性中。这是因为java代码以”{}”为界限,当属性名与参数名一致时,默认情况下,找到的是最近的{}的变量名,即数据传到构造方法后,并未传到属性中。为了明确要访问的变量是类的属性,应在变量名前加this

public Book(String title, double price) {
    this.title = title;
    this.price = price;
}

在开发中,只要访问类中属性,前面必须加this

this调用方法

1.this指的是当前对象,一个类除了属性还有方法,因此可以利用this调用方法。

class Book {
    private String title;
    private double price;

    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    public void print() {
        System.out.println("*********");
    }

    // setter和getter方法略
    public String getInfo() {
        this.print();
        return "书名:" + title + ",价格:" + price;
    }
}

在类中调用普通方法,加不加this都一样。但为了代码的严谨性,最好加this
2.this调用构造方法
多个构造方法间互相调用: this(参数1, 参数2…);
范例:Book类中有三个构造方法,要求不论调用哪个构造方法都会输出一行提示信息一个新的Book类对象产生

class Book {
    private String title;
    private double price;

    public Book() {
        System.out.println("一个新的Book类对象产生");
    }

    public Book(String title) {
        System.out.println("一个新的Book类对象产生");
        this.title = title;
    }

    public Book(String title, double price) {
        System.out.println("一个新的Book类对象产生");
        this.title = title;
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

上述代码中存在重复,要消除重复代码:

class Book {
    private String title;
    private double price;

    public Book() {
        System.out.println("一个新的Book类对象产生");
    }

    public Book(String title) {
        this(); // 调用本类中的无参构造
        this.title = title;
    }

    public Book(String title, double price) {
        this(title); // 调用本类中的单参构造方法
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

上述代码中存在限制:

(1)利用this调用构造方法的语句只能放在构造方法首行;
(2)普通方法无法调用构造方法;
(3)构造方法互相调用时,一定要保留调用的出口,即必须有个构造方法没有调用其他构造方法。

class Book {
    private String title;
    private double price;

    public Book() { // 报错,构造递归调用
        this("Book",1.1);
        System.out.println("一个新的Book类对象产生");
    }

    public Book(String title) {
        this(); // 调用本类中的无参构造
        this.title = title;
    }

    public Book(String title, double price) {
        this(title); // 调用本类中的单参构造方法
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

上述代码会出现”构造方法递归调用”错误,说明构造方法互相调用时,必须至少有一个构造方法没有使用”this()”调用其它构造方法。
3.**范例:**定义一个雇员类(编号,姓名,工资,部门),类中有4个构造方法;

(1)无参构造:编号为0,姓名“无名氏”,工资为0.0,部门为”未定”;
(2)单参构造(传递编号):姓名“临时工”,工资为800.0,部门为”后勤部”;
(3)双参构造(传递编号、姓名):工资为2000.0,部门为”技术部”;
(4)四参构造

实现方式1:不使用this

class Emp {
    private int empNo;
    private String eName;
    private double sal;
    private String dept;

    public Emp() {
        this.empNo = 0;
        this.eName = "无名氏";
        this.sal = 0.0;
        this.dept = "未定";
    }

    public Emp(int empNo) {
        this.empNo = empNo;
        this.eName = "临时工";
        this.sal = 800.0;
        this.dept = "后勤部";
    }

    public Emp(int empNo, String eName) {
        this.empNo = empNo;
        this.eName = eName;
        this.sal = 2000.0;
        this.dept = "技术部";
    }

    public Emp(int empNo, String eName, double sal, String dept) {
        this.empNo = empNo;
        this.eName = eName;
        this.sal = sal;
        this.dept = dept;
    }

    // setter和getter方法略
    public String getInfo() {
        return "雇员编号:" + this.empNo + "\n" +
                "姓   名:" + this.eName + "\n" +
                "工   资:" + this.sal + "\n" +
                "部   门:" + this.dept;
    }
}

实现方式2:使用this

class Emp {
    private int empNo;
    private String eName;
    private double sal;
    private String dept;

    public Emp() {
        this(0,"无名氏",0.0,"");
    }

    public Emp(int empNo) {
        this(empNo,"临时工",800.0,"后勤部");

    }

    public Emp(int empNo, String eName) {
        this(empNo,eName,2000.0,"技术部");
    }

    public Emp(int empNo, String eName, double sal, String dept) {
        this.empNo = empNo;
        this.eName = eName;
        this.sal = sal;
        this.dept = dept;
    }

    // setter和getter方法略
    public String getInfo() {
        return "雇员编号:" + this.empNo + "\n" +
                "姓   名:" + this.eName + "\n" +
                "工   资:" + this.sal + "\n" +
                "部   门:" + this.dept;
    }
}

通过构造方法互相调用解决了代码重复问题。

当前对象

当前对象指的是当前正在调用类中属性或方法的对象

class Book {
    public void print() {
        // 哪个对象调用了print(),this就与该对象指向同一块内存地址
        // this就是当前调用方法的对象
        System.out.println("this = " + this);
    }
}

public class Demo {
    public static void main(String[] args) {
        Book bkA = new Book();
        System.out.println("bkA = " + bkA);  
        // bkA = com.java.demo.Book@1540e19d
        bkA.print(); 
        // this = com.java.demo.Book@1540e19d
        System.out.println( "===============");
        Book bkB = new Book(); 
        // bkB = com.java.demo.Book@677327b6
        System.out.println("bkB = " + bkB); 
        // this = com.java.demo.Book@677327b6
        bkB.print();
    }
}
class A{
    private B b;
    public A(){ // 2.执行A类构造方法
        // 3. 实例化B类对象b,调用B类构造方法
        this.b = new B(this); //此时this是temp
        this.b.get(); // 5. 通过b调用B类的get()
    }
    public void print(){ //8. 执行该方法
        System.out.println("Hello World !");
    }
}
class B{
    private A a;
    public B(A a){ // A a = temp
        this.a = a; // 4. 执行B类构造方法
    }
    public void get(){ // 6. 执行该方法
        this.a.print(); // 7. 调用A类的print()
    }
}
public class Demo {
    public static void main(String[] args) {
        // 1.实例化A类对象,调用A类的无参构造方法
        A temp = new A(); // Hello World !
    }
}

This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(六)/